package com.pickup.service.impl;

import com.pickup.netty.enums.NettyRequestType;
import com.pickup.utils.ChineseUtil;
import com.pickup.utils.SidUtil;
import com.pickup.utils.SmsUtils;
import com.pickup.mapper.*;
import com.pickup.netty.message.ChatMessage;
import com.pickup.netty.message.NettyData;
import com.pickup.netty.server.session.SessionFactory;
import com.pickup.pojo.ChatGroup;
import com.pickup.pojo.UserGroup;
import com.pickup.pojo.Users;
import com.pickup.req.vo.GroupApplyVo;
import com.pickup.req.vo.OperationApply;
import com.pickup.resp.JSONResult;
import com.pickup.service.ChatGroupService;
import com.pickup.utils.*;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
public class ChatGroupServiceImpl implements ChatGroupService {
    @Autowired
    private UsersMapper userMapper;

    @Autowired
    private UsersMapperCustom usersMapperCustom;

    @Autowired
    private MyFriendsMapper myFriendsMapper;

    @Autowired
    private FriendsRequestMapper friendsRequestMapper;

    @Autowired
    private SidUtil sidUtils;

    @Autowired
    private QRCodeUtils qrCodeUtils;

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private UserGroupMapper userGroupMapper;

    @Autowired
    private FastDFSClient fastDFSClient;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserUtil userUtil;

    @Autowired
    private SmsUtils smsUtils;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;



    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public JSONResult createGroup(ChatGroup chatGroup) {
        try {
            String GroupId = sidUtils.nextShort();
            chatGroup.setId(GroupId);

            chatGroup.setGroupName(ChineseUtil.getRandomName());
            chatGroup.setCreateTime(new Date());
            // 小头像
            chatGroup.setFaceImage("M00/00/00/wKgACmIwVNiAM-XLAAQs5R-huUU817_80x80.png");
            // 大头像
            chatGroup.setFaceImageBig("M00/00/00/wKgACmIwVNiAM-XLAAQs5R-huUU817.png");
            // 二维码
            chatGroup.setGroupQrCode(qrCodeUtils.createQRCCode(GroupId));
            try {
                if (groupMapper.createGroup(chatGroup) == 1) {

                    UserGroup userGroup = UserGroup.builder().
                            userId(chatGroup.getUserID()).
                            groupId(GroupId).
                            id(sidUtils.nextShort()).build();
                    return joinGroup(userGroup);
                }
            } catch (Exception e) {
                return JSONResult.build(500, "创建失败！", e.getMessage());
            }
        } catch (Exception e) {
            return JSONResult.build(500, "创建失败！", null);
        }
        return JSONResult.build(500, "创建失败！", null);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public JSONResult joinGroup(UserGroup userGroup) {
        if (userGroup.getGroupId() == null || userGroup.getUserId() == null) {
            return JSONResult.build(500, "加入失败！", null);
        }
        if (userGroupMapper.joinGroup(userGroup) == 1) {
            //Channel sendChannel = SessionFactory.getSession().getGroup(userGroup.getGroupId(), userGroup.getUserId());
            Channel sendChannel = SessionFactory.getSession().getChannel(userGroup.getUserId());
            // 使用websocket主动推送消息到请求发起者，更新他的通讯录列表为最新
            NettyData nettyData = new NettyData();
            nettyData.setChatMessage(new ChatMessage(userGroup.getGroupId(), null, null, null, null, null));
            nettyData.setAction(NettyRequestType.PullGroupMsg);

            if (sendChannel != null) {
                System.out.println(sendChannel);
                sendChannel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(nettyData)));
                return JSONResult.build(200, "加入成功！", null);
            } else {
                redisTemplate.opsForList().leftPush(userGroup.getUserId()+"-groupResult", Objects.requireNonNull(JsonUtils.objectToJson(nettyData)));
            }
        } else {
            return JSONResult.build(500, "加入失败！", null);
        }
        return JSONResult.build(500, "加入失败！", null);
    }


    @Override
    public JSONResult findByAllGroup(String userId) {
        try {
            List<UserGroup> byAllGroup = userGroupMapper.findByAllGroup(userId);
            if (byAllGroup.size() != 0) {
                return JSONResult.build(200, "查找成功！", byAllGroup);
            } else {
                return JSONResult.build(500, "你没有加入群组！", null);
            }
        } catch (Exception e) {
            return JSONResult.build(500, "查找失败！", null);
        }
    }


    @Override
    public JSONResult findGroup(String groupId) {
        List<Users> groupUser = userGroupMapper.findGroup(groupId);

        if (groupUser.size() != 0) {
            return JSONResult.build(200, "查询成功！", groupUser);
        } else {
            return JSONResult.build(500, "查询失败！", null);
        }

    }

    @Override
    public JSONResult findAllGroup(String userId) {
        List<ChatGroup> group = userGroupMapper.findAllGroup(userId);
        try{
            return JSONResult.build(200, "查找成功！", group);

        } catch (Exception e){
            return JSONResult.build(501, "查找失败！", null);
        }
    }

    @Override
    public JSONResult findByGroup(String groupId) {
        // 获取群聊组的群主信息
        try {
            UserGroup byGroup = groupMapper.findByGroup(groupId);
            if (byGroup != null) {
                return JSONResult.build(200, "查找成功！", byGroup);
            }
            return JSONResult.build(500, "查找失败！", null);
        } catch (Exception e) {
            return JSONResult.build(500, "查找失败！", null);
        }

    }

    @Override
    public JSONResult joinByGroup(String groupId, String userId) {
        try {
            UserGroup byUserGroup = userGroupMapper.findByUserGroup(groupId, userId);
            UserGroup byGroup = null;
            if (byUserGroup == null) {
                byGroup = groupMapper.findByGroup(groupId);
            }else {
                return JSONResult.build(500, "你已经在群里！", null);
            }
            if (byGroup != null) {
                // 群主Id保存在redis
                redisTemplate.opsForList().rightPush(byGroup.getUserId() + "-group", userId + "," + groupId);
                return JSONResult.build(200, "申请成功！", null);
            }
            return JSONResult.build(500, "申请失败！", null);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return JSONResult.build(500, "申请失败！", null);
        }
    }


    @Override
    public JSONResult getApplyGroup(String userId) {
        List<String> GroupList = redisTemplate.opsForList().range(userId + "-group", 0, -1);
        List<UserGroup> groupList = new ArrayList<>();
        assert GroupList != null;
        if (GroupList.size() == 0) {
            return JSONResult.build(500, "操作失败！", null);
        } else {
            for (String group : GroupList) {
                String[] split = group.split(",");
                groupList.add(UserGroup.builder().userId(split[0]).groupId(split[1]).build());
            }
            List<GroupApplyVo> groupRequestVOS = userGroupMapper.getApplyGroup(groupList);
            if (groupRequestVOS.size() == 0){
                return JSONResult.build(500, "操作失败！", null);
            }
            return JSONResult.build(200, "操作成功！", groupRequestVOS);
        }
    }

    @Override
    public JSONResult searchGroup(String keyword) {
        List<ChatGroup> chatGroups = groupMapper.searchGroup(keyword);
        if (chatGroups.size() > 0) {
            return JSONResult.build(200, "搜索成功！", chatGroups);
        }
        return JSONResult.build(500, "没有该群组！", null);
    }

    @Override
    public JSONResult deleteGroupRequest(OperationApply operationApply) {
        try {
            Long remove = redisTemplate.opsForList().remove(operationApply.getHandleId() + "-group",
                    0, operationApply.getApplyId() + "," + operationApply.getGroupId());
            if (remove == null || remove == 0){
                return JSONResult.build(500, "操作失败！", null);
            }
            return JSONResult.build(200, "操作成功！", null);
        } catch (Exception e) {
            return JSONResult.build(500, "操作失败！", null);
        }

    }

    @Override
    public JSONResult passGroupRequest(OperationApply operationApply) {
        UserGroup userGroup = UserGroup.builder()
                .id(sidUtils.nextShort())
                .userId(operationApply.getApplyId())
                .groupId(operationApply.getGroupId())
                .build();
        if (joinGroup(userGroup).getStatus() == 200) {
            return deleteGroupRequest(operationApply);
        } else {
            return JSONResult.build(200, "操作失败！", null);
        }
    }
}
